<?php


namespace app\script\controller;

use Events;
use GatewayWorker\BusinessWorker;
use GatewayWorker\Gateway;
use GatewayWorker\Register;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;
use think\Env;
use Workerman\Worker;

/**
 * 以debug（调试）方式启动
 * sudo -u www php think workerman start
 * //以daemon（守护进程）方式启动
 * nohup sudo -u www php think workerman start d &
 * //停止
 * sudo -u www php think workerman stop
 * //重启
 *sudo -u www php think workerman restart
 * //平滑重启
 * sudo -u www php think workerman reload
 * //查看状态
 * sudo -u www php think workerman status
 * Class Workerman
 * @package app\script\controller
 */
class Workerman extends Command
{

    protected function configure()
    {
        $this->setName('workerman')
            ->addArgument('action', Argument::OPTIONAL, "action  start|stop|restart")
            ->addArgument('type', Argument::OPTIONAL, "d -d")
            ->setDescription('workerman chat');
    }

    protected function execute(Input $input, Output $output)
    {
        global $argv;
        $action  = trim($input->getArgument('action'));
        $type    = trim($input->getArgument('type')) ? '-d' : '';
        $argv[0] = 'chat';
        $argv[1] = $action;
        $argv[2] = $type ? '-d' : '';
        $this->start();
    }

    private function start()
    {
        $this->startGateWay();
        $this->startBusinessWorker();
        $this->startRegister();
        Worker::runAll();
    }

    private function startBusinessWorker()
    {
        // bussinessWorker 进程
        $worker = new BusinessWorker();
        // worker名称
        $worker->name = 'YourAppBusinessWorker';
        // bussinessWorker进程数量
        $worker->count = 4;
        //设置处理业务的类,此处制定Events的命名空间
        $worker->eventHandler= Events::class;
        // 服务注册地址
        $register_port           = Env::get('websocket.register_port', 1239) ;
        $worker->registerAddress = '127.0.0.1:' . $register_port;
        // timingwork 进程
//        $timingwork = new  TimingWorker();
//// worker名称
//        $timingwork->name            = 'TimingWorker';
//        $register_port               = Env::get('websocket.register_port', 2239) ;
//        $timingwork->registerAddress = '127.0.0.1:' . $register_port;
//// timingwork进程数量
//        $timingwork->count = Env::get('websocket.process_num', 2);
    }

    private function startGateWay()
    {
        $use_ssl=false;
        // gateway 进程，这里使用Text协议，可以用telnet测试
        //websocket.websocket_port
        $context = [];
        if($use_ssl){
            $context['ssl']=[
                  // 更多ssl选项请参考手册 http://php.net/manual/zh/context.ssl.php
                // 请使用绝对路径
                'local_cert'                 => EXTEND_PATH.'wss/cert/server.pem', // 也可以是crt文件
                'local_pk'                   => EXTEND_PATH.'wss/cert/server.key',
                'verify_peer'                => false,
                // 'allow_self_signed' => true, //如果是自签名证书需要开启此选项
            ];
        }
        $websocket_port = Env::get('websocket.websocket_port', 8200) ;
        $gateway        = new Gateway("websocket://0.0.0.0:" . $websocket_port,$context);
        if($use_ssl)$gateway->transport='ssl';
        // gateway名称，status方便查看
        $gateway->name = 'YourAppGateway';
        // gateway进程数
        $gateway->count = 1;
        // 本机ip，分布式部署时使用内网ip
        $gateway->lanIp = '127.0.0.1';
        // 内部通讯起始端口，假如$gateway->count=4，起始端口为4000
        // 则一般会使用4000 4001 4002 4003 4个端口作为内部通讯端口
        $start_port         = Env::get('websocket.start_port', 3300)  ;
        $gateway->startPort = $start_port;
        // 服务注册地址
        $register_port            = Env::get('websocket.register_port', 1239) ;
        $gateway->registerAddress = '127.0.0.1:' . Env::get('websocket.register_port', $register_port);
        // 心跳间隔
        $gateway->pingInterval         = 55;
        $gateway->pingNotResponseLimit = 0;
        // 心跳数据
        $gateway->pingData = '';
    }

    private function startRegister()
    {
        $register_port = Env::get('websocket.register_port', 1239)  ;
        new Register('text://0.0.0.0:' . $register_port);
    }
}